package com.nycreativity.elecreativity.controller;


import com.nycreativity.elecreativity.aop.ValidateAspect
import com.nycreativity.elecreativity.entity.ResultData
import com.nycreativity.elecreativity.entity.cons.CommonURLConstants
import com.nycreativity.elecreativity.entity.param.PageParam
import com.nycreativity.elecreativity.entity.param.user.*
import com.nycreativity.elecreativity.entity.vo.PageDataVO
import com.nycreativity.elecreativity.entity.vo.user.UserVO
import com.nycreativity.elecreativity.service.SmsService
import com.nycreativity.elecreativity.service.UserService
import com.nycreativity.elecreativity.util.MappingUtil
import com.nycreativity.elecreativity.util.PageUtil
import com.nycreativity.elecreativity.util.usersession.UserContext
import io.swagger.annotations.Api
import io.swagger.annotations.ApiOperation
import org.springframework.validation.BindingResult
import org.springframework.web.bind.annotation.*
import javax.annotation.Resource
import javax.validation.Valid

/**
 * <p>
 *  前端控制器
 * </p>
 *
 * @author sxt && ttxxi
 * @since 2021-03-11
 */
@RestController
@RequestMapping(CommonURLConstants.USER_PREFIX)
@Api(tags = ["用户相关接口"])
class UserController{

    @Resource
    lateinit var userService : UserService
    @Resource
    lateinit var smsService: SmsService

    @GetMapping("/login/password")
    @ApiOperation("用户登录(密码)")
    fun loginViaPassword(phoneNum: String, password: String): ResultData<UserVO>{
        val userVO = userService.loginViaPassword(phoneNum, password) ?: return ResultData.FAILED("登录失败")
        return ResultData.SUCCESS(data = userVO)
    }

    @GetMapping("/login/code")
    @ApiOperation("用户登录(短信),需要先调用获取验证码接口获取验证码")
    fun loginViaCode(phoneNum: String, code: String): ResultData<UserVO>{
        //短信验证
        if (!smsService.validateCode(phoneNum, code)){
            return ResultData.FAILED("验证码错误或已失效")
        }
        val userVO = userService.loginViaPhoneNum(phoneNum) ?: return ResultData.FAILED("该手机号未注册")
        return ResultData.SUCCESS(data = userVO)
    }

    @GetMapping("/login/email")
    @ApiOperation("用户登录(邮箱)")
    fun loginViaEmail(email: String, password: String): ResultData<UserVO>{
        val userVO = userService.loginViaEmail(email, password) ?: return ResultData.FAILED("登录失败")
        return ResultData.SUCCESS(data = userVO)

    }

    @GetMapping("/validCode")
    @ApiOperation("获取手机验证码")
    fun getPhoneValidCode(phoneNum: String): ResultData<Any>{
        smsService.getValidCode(phoneNum)
        return ResultData.SUCCESS()
    }

    @PostMapping
    @ApiOperation("创建用户")
    @ValidateAspect.ParamValidate
    fun createUser(@RequestBody @Valid userAddParam: UserAddParam, bindingResult: BindingResult): ResultData<Any>{
        //短信验证
        if (!smsService.validateCode(userAddParam.phoneNum!!, userAddParam.code!!)){
            return ResultData.FAILED("验证码错误或已失效")
        }

        val res = userService.addUser(userAddParam)
        return if (res){
            ResultData.SUCCESS()
        }else{
            ResultData.FAILED("号码已被注册")
        }
    }

    @GetMapping
    @ApiOperation("获取用户")
    fun getUser(userId : Long): ResultData<UserVO>{

        val user = userService.getById(userId)?:return ResultData.FAILED("获取用户失败")
        return ResultData.SUCCESS(data = MappingUtil.getMappingObject(user, UserVO::class.java))

    }

    @PutMapping
    @ApiOperation("根据id修改用户")
    @ValidateAspect.ParamValidate
    fun updateUser(@RequestBody @Valid userUpdateParam: UserUpdateParam, bindingResult: BindingResult): ResultData<Any>{
        userService.updateById(userUpdateParam);
        return ResultData.SUCCESS()
    }

    @PutMapping("/phoneNum")
    @ApiOperation("修改手机号,具体流程！！！：需要先调用旧手机号获取验证码，再调用/validCode验证，通过后再调用新手机号获取验证码，然后才是调用本接口（本接口验证了新手机号验证码）")
    @ValidateAspect.ParamValidate
    fun updatePhoneNum(@RequestBody @Valid param: UserUpdatePhoneNumParam, bindingResult: BindingResult): ResultData<UserVO>{
        //短信验证
        if (!smsService.validateCode(param.newPhoneNum!!, param.code!!)){
            return ResultData.FAILED("验证码错误或已失效")
        }
        val res = userService.updatePhoneNum(param)
        return if (res){
            ResultData.SUCCESS()
        }else{
            ResultData.FAILED("用户id有误")
        }
    }

    @PutMapping("/password")
    @ApiOperation("修改密码")
    @ValidateAspect.ParamValidate
    fun updatePwd(@RequestBody @Valid param: UserUpdatePwdParam, bindingResult: BindingResult): ResultData<UserVO>{
        val res = userService.updatePwd(param)
        return if (res){
            ResultData.SUCCESS()
        }else{
            ResultData.FAILED("旧号码有误")
        }
    }

    @PutMapping("/forget")
    @ApiOperation("忘记密码")
    @ValidateAspect.ParamValidate
    fun forgetPwd(@RequestBody @Valid param: UserForgetPwdParam, bindingResult: BindingResult): ResultData<Any> {

        //短信验证
        if (!smsService.validateCode(param.phoneNum, param.code)){
            return ResultData.FAILED("验证码错误或已失效")
        }
        val res = userService.updatePwdByPhoneNum(param.phoneNum, param.newPwd)
        return if (res) {
            ResultData.SUCCESS()
        } else {
            ResultData.FAILED("手机号错误")
        }
    }

    @GetMapping("/page")
    @ApiOperation("分页查找用户")
    fun getByPage(pageParam: PageParam): ResultData<PageDataVO<UserVO>> {
        return ResultData.SUCCESS(data = PageUtil.convert(userService.queryByPage(pageParam)))
    }

    @PutMapping("/status")
    @ApiOperation("修改用户状态")
    @ValidateAspect.ParamValidate
    fun updateStatus(@RequestBody @Valid param: UserUpdateStatusParam, bindingResult: BindingResult): ResultData<Any>{
        val res = userService.updateStatus(param)
        return if (res){
            ResultData.SUCCESS()
        }else{
            ResultData.FAILED("请检查请求参数")
        }
    }

    @GetMapping("/checkLogin")
    @ApiOperation("查询登录状态")
    fun checkLogin(): ResultData<Boolean>{
        return ResultData.SUCCESS(data = UserContext.get() != null)
    }

}

